using Spring.Data;
using Spring.Data.Common;
using Spring.Data.Generic;
using Spring.Data.Support;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
namespace AppToolKit.Data.NHibernate
{
	public class SpringDbAdapter : IDbOperation
	{
		private AdoTemplate adoTemplate_;
		public AdoTemplate DbOperationTemplate
		{
			get
			{
				return this.adoTemplate_;
			}
			set
			{
				this.adoTemplate_ = value;
			}
		}
		public CommandBuilderFactory BuilderFactory
		{
			private get;
			set;
		}
		public IDbConnection CreateConnection()
		{
			return this.DbOperationTemplate.DbProvider.CreateConnection();
		}
		public IDbDataAdapter GetDataAdapter()
		{
			return this.DbOperationTemplate.DbProvider.CreateDataAdapter();
		}
		public void LoadDataSet(CommandType commandType, string commandText, ref DataSet dataSet, string[] tableNames)
		{
			this.DbOperationTemplate.ClassicAdoTemplate.DataSetFill(dataSet, commandType, commandText, tableNames);
		}
		public DataSet ExecuteDataSet(string storedProcedureName, params object[] parameterValues)
		{
			IDbParameters dbParameters = this.PrepareStoreProcdureParameters(storedProcedureName, parameterValues);
			return this.DbOperationTemplate.ClassicAdoTemplate.DataSetCreateWithParams(CommandType.StoredProcedure, storedProcedureName, dbParameters);
		}
		public DataSet ExecuteDataSet(CommandType commandType, string commandText)
		{
			return this.DbOperationTemplate.ClassicAdoTemplate.DataSetCreate(commandType, commandText);
		}
		public object ExecuteScalar(CommandType commandType, string commandText)
		{
			return this.DbOperationTemplate.ExecuteScalar(commandType, commandText);
		}
		public int ExecuteNonQuery(CommandType commandType, string commandText)
		{
			return this.DbOperationTemplate.ExecuteNonQuery(commandType, commandText);
		}
		public IDataReader ExecuteReader(CommandType commandType, string commandText)
		{
			IDbConnection dbConnection = this.DbOperationTemplate.DbProvider.CreateConnection();
			IDbCommand dbCommand = dbConnection.CreateCommand();
			dbCommand.CommandType = commandType;
			dbCommand.CommandText = commandText;
			IDataReader result;
			try
			{
				dbConnection.Open();
				result = dbCommand.ExecuteReader(CommandBehavior.CloseConnection);
			}
			catch
			{
				if (dbConnection != null)
				{
					dbConnection.Close();
				}
				throw;
			}
			finally
			{
				dbCommand.Dispose();
			}
			return result;
		}
		public int ExecuteNonQuery(string storedProcedureName, params object[] parameterValues)
		{
			IDbParameters dbParameters = this.PrepareStoreProcdureParameters(storedProcedureName, parameterValues);
			return this.DbOperationTemplate.ExecuteNonQuery(CommandType.StoredProcedure, storedProcedureName, dbParameters);
		}
		public void ExecuteReader(CommandType commandType, string commandText, ExecuteReaderCallbackWrapper callbackWrapper)
		{
			this.DoExecuteReader(delegate(IDbCommand cmd)
			{
				cmd.CommandType = commandType;
				cmd.CommandText = commandText;
			}
			, callbackWrapper);
		}
		public void UpdateDataSet(string selectSql, DataSet ds)
		{
			IDbConnection dbConnection = this.CreateConnection();
			DbCommand dbCommand = (DbCommand)dbConnection.CreateCommand();
			dbCommand.CommandType = CommandType.Text;
			dbCommand.CommandText = selectSql;
			DbDataAdapter dbDataAdapter = (DbDataAdapter)this.GetDataAdapter();
			dbDataAdapter.SelectCommand = dbCommand;
			DbCommandBuilder dbCommandBuilder = (DbCommandBuilder)this.DbOperationTemplate.DbProvider.CreateCommandBuilder();
			dbCommandBuilder.DataAdapter = dbDataAdapter;
			dbDataAdapter.InsertCommand = dbCommandBuilder.GetInsertCommand();
			dbDataAdapter.UpdateCommand = dbCommandBuilder.GetUpdateCommand();
			dbDataAdapter.DeleteCommand = dbCommandBuilder.GetDeleteCommand();
			try
			{
				dbDataAdapter.Update(ds);
			}
			finally
			{
				dbConnection.Dispose();
				dbCommand.Dispose();
			}
		}
		public int ExecuteNonQuery(IDbQuery wrapper)
		{
			IDbParameters paramsFromDbQuery = this.GetParamsFromDbQuery(wrapper);
			int result;
			if (paramsFromDbQuery != null)
			{
				result = this.DbOperationTemplate.ClassicAdoTemplate.ExecuteNonQuery(wrapper.CommandType, wrapper.Query, paramsFromDbQuery);
			}
			else
			{
				result = this.DbOperationTemplate.ClassicAdoTemplate.ExecuteNonQuery(wrapper.CommandType, wrapper.Query);
			}
			return result;
		}
		public DataSet ExecuteDataSet(IDbQuery query)
		{
			IDbParameters paramsFromDbQuery = this.GetParamsFromDbQuery(query);
			DataSet result;
			if (paramsFromDbQuery != null)
			{
				result = this.DbOperationTemplate.ClassicAdoTemplate.DataSetCreateWithParams(query.CommandType, query.Query, paramsFromDbQuery);
			}
			else
			{
				result = this.DbOperationTemplate.ClassicAdoTemplate.DataSetCreate(query.CommandType, query.Query);
			}
			return result;
		}
		public void ExecuteReader(IDbQuery query, ExecuteReaderCallbackWrapper callbackWrapper)
		{
			this.DoExecuteReader(delegate(IDbCommand cmd)
			{
				cmd.CommandType = query.CommandType;
				cmd.CommandText = query.Query;
				this.FillParamsFromDbQuery(query, cmd);
			}
			, callbackWrapper);
		}
		private void DoExecuteReader(CommandSetterDelegate cmdSetter, ExecuteReaderCallbackWrapper callbackWrapper)
		{
			ConnectionTxPair connectionTxPair = ConnectionUtils.GetConnectionTxPair(this.DbOperationTemplate.DbProvider);
			IDbConnection connection = connectionTxPair.Connection;
			IDbCommand dbCommand = null;
			IDataReader dataReader = null;
			try
			{
				dbCommand = this.DbOperationTemplate.DbProvider.CreateCommand();
				dbCommand.Connection = connection;
				dbCommand.Transaction = connectionTxPair.Transaction;
				cmdSetter.Invoke(dbCommand);
				dataReader = dbCommand.ExecuteReader();
				callbackWrapper.OnCallback(dataReader);
			}
			catch
			{
				AdoUtils.DisposeCommand(dbCommand);
				dbCommand = null;
				ConnectionUtils.DisposeConnection(connectionTxPair.Connection, this.DbOperationTemplate.DbProvider);
				connectionTxPair.Connection=null;
				throw;
			}
			finally
			{
				if (dataReader != null)
				{
					dataReader.Close();
					dataReader.Dispose();
				}
				AdoUtils.DisposeCommand(dbCommand);
				ConnectionUtils.DisposeConnection(connectionTxPair.Connection, this.DbOperationTemplate.DbProvider);
			}
		}
		private IDbParameters GetParamsFromDbQuery(IDbQuery wrapper)
		{
			IDbParameters dbParameters = this.DbOperationTemplate.ClassicAdoTemplate.CreateDbParameters();
			List<QueryParameter> parameters = wrapper.Parameters;
			IDbParameters result;
			if (parameters != null && parameters.Count > 0)
			{
				foreach (QueryParameter current in parameters)
				{
					IDataParameter dataParameter = dbParameters.Add(current.Name, current.Type);
					dataParameter.Value = current.Value;
				}
				result = dbParameters;
			}
			else
			{
				result = null;
			}
			return result;
		}
		private void FillParamsFromDbQuery(IDbQuery query, IDbCommand cmd)
		{
			List<QueryParameter> parameters = query.Parameters;
			if (parameters != null && parameters.Count > 0)
			{
				foreach (QueryParameter current in parameters)
				{
					IDataParameter dataParameter = cmd.CreateParameter();
					dataParameter.DbType = current.Type;
					dataParameter.ParameterName = current.Name;
					dataParameter.Value = current.Value;
					cmd.Parameters.Add(dataParameter);
				}
			}
		}
		public object ExecuteScalar(IDbQuery dbQuery)
		{
			IDbParameters paramsFromDbQuery = this.GetParamsFromDbQuery(dbQuery);
			object result;
			if (paramsFromDbQuery != null)
			{
				result = this.DbOperationTemplate.ClassicAdoTemplate.ExecuteScalar(dbQuery.CommandType, dbQuery.Query, paramsFromDbQuery);
			}
			else
			{
				result = this.DbOperationTemplate.ClassicAdoTemplate.ExecuteScalar(dbQuery.CommandType, dbQuery.Query);
			}
			return result;
		}
		public ICommandBuilder GetCommandBuilder()
		{
			return this.BuilderFactory.GetBuilder(this.adoTemplate_.DbProvider.DbMetadata.ConnectionType);
		}
		private IDbParameters PrepareStoreProcdureParameters(string storedProcedureName, object[] parameterValues)
		{
			IDbParameters dbParameters = this.DbOperationTemplate.CreateDbParameters();
			IDataParameter[] array = this.DbOperationTemplate.DeriveParameters(storedProcedureName);
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Value = ((parameterValues[i] == null) ? DBNull.Value : parameterValues[i]);
				dbParameters.AddParameter(array[i]);
			}
			return dbParameters;
		}
	}
}
